package com.xishu.task;

import com.xishu.config.Constant;
import com.xishu.controller.ShopController;
import com.xishu.entity.Company;
import com.xishu.entity.shop.Shop;
import com.xishu.service.CommonService;
import com.xishu.service.ShopService;
import com.xishu.util.DateUtil;
import com.xishu.util.JRedisUtil;
import com.xishu.util.MongoId;
import com.xishu.util.Tools;
import org.apache.logging.log4j.ThreadContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.text.ParseException;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 定时5分执行一次
 */
@Component
public class AutoCloseShopTask implements Tools {
    private ShopService shopService = ShopService.getInstance();
    private CommonService commonService = CommonService.getInstance();
    private static Logger logger = LoggerFactory.getLogger(AutoCloseShopTask.class);

    @Scheduled(cron = "0 0/5 * * * ?")
    public void autoCloseShop() {
        try {
            ThreadContext.put(Constant.REQUEST_ID, "auto close shop");
            logger.info("automatic close shop timed task");
            List<Company> companyInDbList = commonService.searchAll(Company.class);
            //13位时间戳，单位毫秒，
            long currentTimeMillis = System.currentTimeMillis();
            //收集前30分钟需要自动关闭的公司-
            List<Company> satisfyCompanyList = new ArrayList<>();
            List<Company> afterFilterCompanyList = companyInDbList.stream().filter((company) -> company.getAutoCloseShop() != null
                    && company.getAutoCloseShop() && company.getAutoCloseShopDate() != null).collect(Collectors.toList());
            //判断过滤后的集合
            for (Company company : afterFilterCompanyList) {
                //跨天处理
                boolean spanDay = spanDay(company.getAutoCloseShopDate());
                logger.info("Is it the same day {}", spanDay);
                long companyCloseTime = replaceTime(company.getAutoCloseShopDate());
                //满足跨天条件，或者当前时间前半小时需要关闭的。
                if (spanDay || (companyCloseTime <= currentTimeMillis && companyCloseTime >= currentTimeMillis - 30 * 60 * 1000)) {
                    //符合条件的公司就放到公司集合
                    logger.info("Successfully added to the collection {}", company.getId());
                    satisfyCompanyList.add(company);
                }

            }

            logger.info("Start closing shop");
            for (Company company : satisfyCompanyList) {
                logger.info("check the company {}", company.getId());
                List<Shop> closeShopList = new ArrayList<>();
                List<Shop> shopListInDb = shopService.findShopListByCompanyId(company.getId());

                for (Shop shopClose : shopListInDb) {
                    String shopKey = String.valueOf("AutoClose:" + shopClose.getId()) + Constant.AUTO_CLOSE_SHOPID_TO_KEY;
                    boolean existsKey = JRedisUtil.exists(shopKey);
                    Boolean shopCloseBusinessStatus = shopClose.getBusinessStatus();
                    if (!existsKey && shopCloseBusinessStatus != null && shopCloseBusinessStatus) {
                        logger.info("add the shop {} to close list", shopClose.getId());
                        closeShopList.add(shopClose);
                    }
                }

                autoCloseShop(closeShopList);
            }
        } catch (Exception e) {
            logger.error("e", e);
        }

    }

    //特殊处理跨天问题
    private boolean spanDay(String autoCloseShop) {
        //把用户的时间固定时间，替换成在当天的时间
        long companyCloseTime = replaceTime(autoCloseShop);
        //现在时间
        long currentTimeMillis = System.currentTimeMillis();
        //每天开始的时间00:00
        long startTimeInDay = DateUtil.startTimeInDay(currentTimeMillis);
        //一天结束的时间23:59
        long endTimeInDay = DateUtil.endTimeInDay(companyCloseTime);
        //当前时间在每天的00:00-00:00：30之间
        if (currentTimeMillis < startTimeInDay + 30 * 60 * 1000) {
            //店铺关闭时间在23:30-23:59之间
            if (companyCloseTime > endTimeInDay - 30 * 60 * 1000) {
                logger.info("Tackle the tasks of the previous day");
                return true;
            }
        }
        return false;
    }

    /**
     * 构建参数shop 自动关闭分
     *
     * @throws Exception
     */
    private void autoCloseShop(List<Shop> shopList) {
        //再调用修改分店的接口，依次关闭分店
        for (Shop shop : shopList) {
            Shop companyShop = new Shop();
            companyShop.setId(shop.getId());
            companyShop.setBusinessStatus(false);
            ShopController shopController = new ShopController();
            try {
                //关闭店铺的接口，构建参数
                shopController.modify(companyShop);
                //保存到jedis，过期时间2
                JRedisUtil.setKV("AutoClose:" + String.valueOf(shop.getId()) + Constant.AUTO_CLOSE_SHOPID_TO_KEY, 2 * 60 * 60, String.valueOf(System.currentTimeMillis()));
                logger.info("save to redis {}", shop.getId());
            } catch (Exception e) {
                logger.error("e", e);
            }
        }
    }

    /**
     * 因为用户保存的时间是固定时间戳，所以要替换成当天的时间戳做比较
     *
     * @param
     * @return
     * @throws ParseException
     */
    private Long replaceTime(String autoCloseShopTime) {
        logger.info("Start time of replacement {} ", autoCloseShopTime);
        long currentTimeMillis = System.currentTimeMillis();
        int year = DateUtil.getYear(currentTimeMillis);
        int month = DateUtil.getMonth(currentTimeMillis);
        int day = DateUtil.getDay(currentTimeMillis);
        String[] split = autoCloseShopTime.split(":");
        int hour = Integer.parseInt(split[0]);
        int minute = Integer.parseInt(split[1]);
        return DateUtil.dateToTime(year, month, day, hour, minute);
    }
}
